In a storage controller, a dynamic random access memory (DRAM) buffer pool is used to de-stage writes to memory devices, such as a hard disk drive (HDD), a solid state drive (SSD), etc. to provide fast response to the upper layers, and can also be used as a read cache. In a mixed topology, where the storage controller is connected to both a solid state drive (SSD) and an HDD (or some other fast and slow storage mediums) SSD and HDD Virtual Drives (VDs)s share the same DRAM buffer pool. Since SSD VDs can flush and de-stage data faster from DRAM, buffers corresponding to SSD VDs are freed up much faster than HDD VDs. These newly freed buffers can in turn be taken by incoming HDD input/output (I/O) requests, which rapidly fills all of the buffers in the pool and leads to severe starvation and lower performance for the SSDs.
Also, in many storage applications, there are workloads for which low write latency takes priority. Typically, these are low queue depth workloads, and the success of providing low latency depends on the availability of free buffers for incoming writes. Thus, low latency workloads will suffer if other workloads use all the buffers in the pool, and the storage controller must wait for free buffers.
One way of addressing the above problem may be to introduce a hard partition of the buffers between HDD, SSD and Low Latency workloads. However, this scheme is wasteful and suboptimal when any of the three workloads are either not present or idle. In that case, the reserved buffers for each idle or unused workload are unutilized even though the buffers could have been better utilized by some other workload that may be starved for extra buffers. Accordingly, it is desired to introduce a flexible buffer management scheme that reacts smoothly and automatically to changes in buffer demand, which can lead to a reduction of wasted buffer space.